/**
 * @date 2006-7-13
 */

package org.nanhill.xmlro;

import java.nio.charset.Charset;

import sun.misc.BASE64Encoder;

/**
 * @author alin [xalinx at gmail dot com]
 * @date 2006-7-13
 */
public abstract class AbstractXmlroOutput implements XmlroOutput {

	private static final BASE64Encoder base64Encoder = new BASE64Encoder();

	private Object parsed;

	protected StringBuilder product;

	protected Charset utf8CharSet = Charset.forName("UTF-8");

	public AbstractXmlroOutput(StringBuilder builder) {
		this.product = builder;
	}

	public AbstractXmlroOutput(Object obj, StringBuilder builder) {
		this(builder);
		this.parsed = obj;
	}

	public AbstractXmlroOutput(Object obj) {
		this(obj, new StringBuilder());
	}

	public AbstractXmlroOutput() {
		this(new StringBuilder());
	}

	public StringBuilder getProduct() {
		return this.product;
	}

	public void setParsed(Object obj) {
		this.parsed = obj;
	}

	public void writeObject(Object object) throws XmlroException {
		if (object == null) {
			this.writeNull();
		} else {
			Serializer serializer = this.getSerializer(object.getClass());
			if (null == serializer)
				throw new IllegalArgumentException("now such serializer: "
						+ object.getClass());
			serializer.writeObject(object, this);
		}
	}

	/**
	 * Prints a string as ascii to the stream.
	 * 
	 * @param s
	 *            the ascii string to print.
	 */
	protected void print(String s) {
		append(s);
	}

	protected String encodeBase64(byte[] v) {
		return base64Encoder.encode(v);
	}

	protected void append(String v) {
		product.append(v);
	}

	protected void append(char v) {
		product.append(v);
	}

	protected void append(char[] v) {
		product.append(v);
	}

	protected Object getParsed() {
		return this.parsed;
	}

	protected void printBase64(String s) {
		printBase64((s.getBytes()));
	}

	protected void printBase64(byte[] v) {
		print(this.encodeBase64(v));
	}

	/**
	 * Prints a double to the stream.
	 * 
	 * @param v
	 *            the double to print.
	 */
	protected void print(double v) {
		print(String.valueOf(v));
	}

	protected void print(long v) {
		print(String.valueOf(v));
	}

	/**
	 * Prints an integer to the stream.
	 * 
	 * @param v
	 *            the integer to print.
	 */
	protected void print(int v) {
		print(String.valueOf(v));
	}

	/**
	 * Prints a char to the stream.
	 * 
	 * @param v
	 *            the char to print.
	 */
	protected void print(char v) {
		append(v);
	}

	protected abstract Serializer getSerializer(Class clz);

}
